package com.xuecheng.content.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.CourseBaseVo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioTemplate;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.CoursePub;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.CoursePubService;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-12-03
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    //分页、条件查询
    /*@Override
    public ResponseResult<CourseBaseVo> findByPage(CourseDto courseDto, PageRequest pageRequest) {
        //构造分页对象
        Page<CourseBase> page = new Page<>(pageRequest.getPageNo(), pageRequest.getPageSize());
        //构造查询条件
        LambdaQueryWrapper<CourseBase> qw = new LambdaQueryWrapper<>();
        //模糊查询课程名称
        qw.like(StrUtil.isNotEmpty(courseDto.getCourseName()),CourseBase::getName,courseDto.getCourseName());
        //课程状态
        qw.eq(StrUtil.isNotEmpty(courseDto.getAuditStatus()),CourseBase::getAuditStatus,courseDto.getAuditStatus());
        //课程类型
        qw.eq(StrUtil.isNotEmpty(courseDto.getTeachmode()),CourseBase::getTeachmode,courseDto.getTeachmode());
        //开启分页
        page = this.page(page,qw);
        //数据库实体转vo
        List<CourseBase> courseBaseList = page.getRecords();
        List<CourseBaseVo> voList = new ArrayList<>();
        for (CourseBase courseBase : courseBaseList) {
            //复制属性
            CourseBaseVo vo = BeanHelper.copyProperties(courseBase, CourseBaseVo.class);
            voList.add(vo);
        }
        //返回结果
        return PageResponseResult.okResult(page.getTotal(),voList);
    }*/

    @Override
    public ResponseResult<CourseBaseVo> findByPage(CourseDto courseDto, PageRequest pageRequest) {
        //构建分页
        Page<CourseBase> page = new Page<>(pageRequest.getPageNo(), pageRequest.getPageSize());
        //构建条件（链式编程）
        page = this.lambdaQuery()
                .like(StrUtil.isNotEmpty(courseDto.getCourseName()), CourseBase::getName, courseDto.getCourseName()) // 课程名称
                .eq(StrUtil.isNotEmpty(courseDto.getAuditStatus()), CourseBase::getAuditStatus, courseDto.getAuditStatus()) // 课程状态
                .eq(StrUtil.isNotEmpty(courseDto.getTeachmode()), CourseBase::getTeachmode, courseDto.getTeachmode()) // 课程类型
                .page(page); // 开启分页查询

        //转为vo
        List<CourseBaseVo> voList = BeanHelper.copyWithCollection(page.getRecords(), CourseBaseVo.class);
        //返回结果
        return PageResponseResult.okResult(page.getTotal(), voList);
    }

    @Autowired
    private TeachplanService teachplanService; //课程大纲

    //课程新增
    @Override
    public ResponseResult<Map> saveCourseBase(CourseBaseDto courseBaseDto) {
        //校验参数 新增时不校验id、价格
        if (!StrUtil.isAllNotEmpty(courseBaseDto.getName(),courseBaseDto.getTags(),courseBaseDto.getMt(),
                                    courseBaseDto.getSt(),courseBaseDto.getGrade())){
            //有一个为空，不允许新增
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //dto转为数据库实体
        CourseBase courseBase = BeanHelper.copyProperties(courseBaseDto, CourseBase.class);
        //补全信息
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);//未提交审核
        courseBase.setPlanNum(0);//课程小节
        courseBase.setCreateDate(new Date());//新增时间
        //写入数据库
        boolean isSave = this.save(courseBase);
        if (!isSave){
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //TODO 初始化一级大纲
        Teachplan teachplan = new Teachplan();
        teachplan.setPname(courseBase.getName());//大纲名称
        teachplan.setParentid(0L);//父节点
        teachplan.setGrade(1);//一级目录
        teachplan.setDescription(courseBase.getDescription());//课程介绍
        teachplan.setCourseId(courseBase.getId());//课程id
        teachplan.setCreateDate(new Date());//创建时间
        //写入数据库
        teachplanService.save(teachplan);
        //返回课程id
        Map<String,Long> map=new HashMap<>();
        map.put("courseBaseId",courseBase.getId());
        return ResponseResult.okResult(map);
    }

    //课程修改
    @Override
    public ResponseResult<Map> updateCourseBase(CourseBaseDto courseBaseDto) {
        //校验参数 修改时不校验价格
        if (!StrUtil.isAllNotEmpty(courseBaseDto.getName(),courseBaseDto.getTags(),courseBaseDto.getMt(),
                courseBaseDto.getSt(),courseBaseDto.getGrade())){
            //有一个为空，不允许新增
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //校验id
        if (ObjectUtil.isEmpty(courseBaseDto.getId())){
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //校验课程状态，已发布的课程不能修改
        //查询数据库
        CourseBase courseBase_database = this.getById(courseBaseDto.getId());
        //判断状态
        if (StrUtil.equals(courseBase_database.getAuditStatus(),CourseConstants.AUDIT_PUBLISHED_STATUS)){
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //dto转为数据库实体
        CourseBase courseBase_new = BeanHelper.copyProperties(courseBaseDto, CourseBase.class);
        courseBase_new.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);//修改后需要再次审核
        //更新数据库
        boolean isUpdate = this.updateById(courseBase_new);
        if (!isUpdate){
            throw new BusinessException(ErrorCode.UPDATEEERROR);
        }
        //TODO 更新一级大纲
        //查询一级大纲
        Teachplan teachplan = teachplanService.lambdaQuery().eq(Teachplan::getCourseId, courseBase_new.getId())
                .eq(Teachplan::getGrade, 1).one();
        teachplan.setPname(courseBase_new.getName());//重新设置课程名
        teachplan.setDescription(courseBase_new.getDescription());//设置描述信息
        teachplan.setChangeDate(new Date());//设置更新时间
        //更新数据库
        teachplanService.updateById(teachplan);
        //返回课程id
        Map<String,Long> map=new HashMap<>();
        map.put("courseBaseId",courseBase_new.getId());
        return ResponseResult.okResult(map);
    }

    @Autowired
    private MinioTemplate minioTemplate;

    //课程删除
    @Override
    @Transactional
    public ResponseResult deleteCourseBase(Long courseId) {
        //校验课程状态 已发布的课程不能删除
        //查询数据库
        CourseBase courseBase = this.getById(courseId);
        //判断状态
        if (StrUtil.equals(courseBase.getAuditStatus(), CourseConstants.AUDIT_PUBLISHED_STATUS)){
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //TODO 删除课程大纲
        //课程下有课程计划不允许删除
        Long count = teachplanService.lambdaQuery().eq(Teachplan::getCourseId, courseId).count();
        //大于1则表示目录和节点还存在
        if (count>1){
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //删除一级大纲
        LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
        qw.eq(Teachplan::getCourseId,courseId);
        teachplanService.remove(qw);
        //删除课程
        boolean isDelete = this.removeById(courseId);
        if (!isDelete){
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //删除minio课程的图片
        //获取文件地址
        String picUrl = courseBase.getPic();
        //删除文件
        minioTemplate.deleteObject(picUrl);
        return ResponseResult.okResult();
    }

    @Autowired
    private CoursePubService coursePubService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //课程下架
    @Override
    @Transactional
    public ResponseResult offline(Long courseId) {
        //校验前端参数
        if (courseId==null){
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //根据课程id查询课程对象
        CourseBase courseBase = this.getById(courseId);
        //校验课程状态 只有已发布的才能下架
        if (!StrUtil.equals(courseBase.getAuditStatus(),CourseConstants.AUDIT_PUBLISHED_STATUS)){
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //删除课程发布对象
        LambdaQueryWrapper<CoursePub> qw = new LambdaQueryWrapper<>();
        qw.eq(CoursePub::getCourseId,courseId);
        coursePubService.remove(qw);
        //删除minio文件
        minioTemplate.deleteHtml(courseId.toString());
        //发送异步mq消息 消息内容为courseId
        rabbitTemplate.convertAndSend("content-exchange","course.offline",courseId);
        //更新课程状态
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNLINE_STATUS);
        this.updateById(courseBase);
        //返回200
        return ResponseResult.okResult();
    }
}
